QuickSortLib:

;****************************************************
; Quick sort of the array in the memory.
;
;  ptrArray       - pointer to the memory array.
;  ElementSize    - size of one array element in bytes.
;  iBegin         - index of the first element
;  iEnd           - index of the last element
;  ptrCompareProc - pointer to procedure that compares two elements.
;
; ptrCompareProc have interface:
;  proc CompareSomething, ptrElement1, ptrElement2
;    returns: c=1 if elements are not properly sorted.
;             c=0 if elements are sorted, i.e.
;                 element1 should be before element2
;****************************************************


proc QSort ptrArray, ElementSize, iBegin, iEnd, ptrCompareProc
	push	esi edi ebx
	mov	esi, [ptrArray]
	mov	edi, [ptrCompareProc]
	mov	ebx, [ElementSize]

	stdcall DoQSort, [iBegin], [iEnd]
	pop	ebx edi esi
	ret
endp

;*****************************************************
; Procedure for internal call from QSort procedure.
;*****************************************************
proc DoQSort Left, Right
	push	ecx

	mov	ecx, [Left]	; i variable
	mov	eax, ecx
	mov	edx, [Right]	; j variable
	add	eax, edx
	sar	eax, 1
	imul	eax, ebx
	imul	ecx, ebx
	imul	edx, ebx
	add	eax, esi
	add	ecx, esi
	add	edx, esi

.repeat:
	sub	ecx, ebx
	add	edx, ebx

.whylei:
	add	ecx, ebx
	stdcall edi, ecx, eax
	jnc	.whylei

.whylej:
	sub	edx, ebx
	stdcall edi, eax, edx
	jnc	.whylej

	cmp	edx, ecx
	jl	.next

	call	SwapElements

	push	edx
	cmp	eax, ecx
	je	@f
	mov	[esp], ecx
	cmp	eax, edx
	je	@f

	mov	[esp], eax
@@:
	pop	eax

	add	ecx, ebx
	sub	edx, ebx

.next:
	cmp	ecx, edx
	jle	.repeat

	mov	eax, edx
	sub	eax, esi
	cdq
	idiv	ebx

	cmp	[Left], eax
	jge	.leftok

	stdcall DoQSort, [Left], eax

.leftok:
	mov	eax, ecx
	sub	eax, esi
	cdq
	idiv	ebx

	cmp	eax, [Right]
	jge	.rightok

	stdcall DoQSort, eax, [Right]

.rightok:
	pop	ecx
	ret
endp



;********************************************
; Swaps two elements of the array with
; pointers in:
;   Element1 - ecx
;   Element2 - edx
;   ElementSize - ebx
;********************************************
proc SwapElements
	push	esi eax

	xor	esi, esi
.loop:
	mov	al, [ecx+esi]
	xchg	al, [edx+esi]
	mov	[ecx+esi], al

	inc	esi
	cmp	esi, ebx
	jne	.loop

	pop	eax esi
	ret
endp




proc CompareIntAscending ptrElement1, ptrElement2
	push	eax esi edi

	mov	esi, [ptrElement1]
	mov	edi, [ptrElement2]

	mov	eax, [esi]
	cmp	eax, [edi]
	jl	.qfalse

	stc
	pop	edi esi eax
	ret


.qfalse:
	clc
	pop	edi esi eax
	ret
endp



DispSize 'QSort lib', $ - QuickSortLib